<template>
  <div class="material-image-read">
    <div class="header">
      <div class="header-left">
        <el-checkbox
          :model-value="isAllChecked"
          :indeterminate="isIndeterminate"
          label="全选"
          @change="onAllChange"
        />
      </div>
      <div class="header-right">
        <el-button @click="handleClear"> 清空 </el-button>

        <el-button
          type="primary"
          plain
          @click="handleBatchCreate"
          :disabled="getTextCheck.length == 0"
        >
          填充
        </el-button>

        <el-button type="primary" @click="handleRead"> 读取 </el-button>
      </div>
    </div>
    <div class="text-list">
      <div
        :class="['text-list-item']"
        v-for="(item, index) in elementList"
        :key="item.id"
        @click.stop="onItemChange(item, index)"
        @touchstart="onTouchstart(item, index)"
        @touchend="touchEnd(item, index)"
        @mousedown="onTouchstart(item, index)"
        @mouseup="touchEnd(item, index)"
      >
        <div class="text-list-warp" v-loading="item.loading">
          <el-checkbox
            class="text-list-checkbox"
            @click.stop
            @change="onItemChange(item, index)"
            :model-value="textCheckMap[item.id]"
          />
          <img class="text-list-img" :src="item.url" />
        </div>
      </div>
    </div>

    <c-dialog title="读取剪切板内容" :destroy-on-close="false" :width="600" name="editable-content">
      <el-space class="editable-handle">
        <c-select v-model="editGetType" :filterable="true" :clearable="true" width="160px">
          <el-option :value="0" label="自定义属性"></el-option>
          <el-option :value="1" label="默认"></el-option>
          <el-option :value="2" label="微信公众号h5"></el-option>
        </c-select>
        <c-input v-if="editGetType == 0" v-model="editGetInput" placeholder="请输入"></c-input>
      </el-space>
      <div
        id="editable"
        class="read-editable-content"
        contenteditable="true"
        placeholder="请在你想拷贝内容的网页直接选中复制，然后 Ctrl+V 粘贴内容"
        @input="onEditableInput"
      ></div>
      <div class="dialog-footer">
        <el-button plain @click="handleClose"> 取 消 </el-button>
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
      </div>
    </c-dialog>

    <el-image-viewer
      v-if="showPreview"
      :url-list="elementList.map((v) => v.url)"
      :initial-index="imageViewerIndex"
      @close="showPreview = false"
    />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { Delete, Loading } from '@element-plus/icons-vue';
import { v4 } from 'uuid';
import { fileFormUrl } from '@/utils/tools.js';
import { getUrlToBlob } from '@/apis/upload.js';

// store modal
import { useModalStore } from '@/pinia/modules/modal';
const modalStore = useModalStore();

const emit = defineEmits(['out-text', 'on-batch', 'on-fill']);

const editGetType = ref(1);

const editGetInput = ref('');

const textCheckMap = ref({});

const elementList = ref([]);

const getTextCheck = computed(() => {
  return elementList.value.filter((v) => textCheckMap.value[v.id]);
});

// 是否全选
const isAllChecked = computed(
  () => elementList.value.length > 0 && getTextCheck.value.length === elementList.value.length,
);

// 部分数据勾选状态
const isIndeterminate = computed(() =>
  isAllChecked.value ? false : getTextCheck.value.length > 0,
);

const onEditableInput = (e) => {
  if (e.target.innerText.trim()) {
    e.target.setAttribute('placeholder', '');
  } else {
    e.target.innerHTML = '';
    e.target.setAttribute(
      'placeholder',
      '请在你想拷贝内容的网页直接选中复制，然后 Ctrl+V 粘贴内容',
    );
  }
};

const handleRead = () => {
  modalStore.openModal('editable-content', {});
};

const handleClose = () => {
  modalStore.closeModal('editable-content');
};

const handleSubmit = () => {
  const element = document.getElementById('editable');
  const imgElements = element.querySelectorAll('img');

  elementList.value = Array.from(imgElements)
    .map((img) => {
      let url = img.getAttribute('src');

      if (editGetType.value == 0 && editGetInput.value) {
        url = img.getAttribute(editGetInput.value);
      }

      if (editGetType.value == 1) {
        url = img.getAttribute('src');
      }

      if (editGetType.value == 2) {
        const data_url = img.getAttribute('data-src');
        let ori_url = data_url;

        try {
          let ori_arr = data_url.split('?')[0].split('/');
          ori_arr[ori_arr.length - 1] = 0;
          ori_url = ori_arr.join('/');
        } catch (error) {}

        url = ori_url || '';
      }

      console.log(url, 'url----');

      return { url: url, id: v4(), isBase64: url.startsWith('data:image/') };
    })
    .filter((v) => v.url !== null && v.url !== '');

  console.log(elementList.value, 'elementList.value');

  handleClose();

  setTimeout(() => {
    onAllChange(true);
  }, 100);
};

const handleBatchCreate = async () => {
  console.log(textCheckMap.value, ' textCheckMap');

  for (const item of getTextCheck.value) {
    const idx = elementList.value.findIndex((v) => v.id == item.id);

    elementList.value[idx]['loading'] = true;

    let obj = { status: 0, loading: false };

    const { binaryBuffer, type } = await getUrlToBlob({ url: item.url }).catch((err) => err);

    if (binaryBuffer && type) {
      let binaryData = new Uint8Array(binaryBuffer.data);

      console.log(binaryBuffer.data, binaryData, 'binaryBuffer');

      // 创建Blob
      const blob = new Blob([binaryData], { type: type });

      // 创建一个File对象
      const file = new File([blob], Date.now() + '.png', {
        type: type,
        lastModified: new Date().getTime(),
      });

      obj['file'] = file;
      obj['imageUrl'] = fileFormUrl(file);

      console.log(obj, 'image');
      emit('on-fill', obj);
    }

    elementList.value[idx]['loading'] = false;
  }
};

const onAllChange = (e) => {
  console.log(e, 'e');
  for (const item of elementList.value) {
    textCheckMap.value[item.id] = e;
  }

  console.log(textCheckMap.value, isAllChecked.value, 'textCheckMap.value2');
};

const onItemChange = (item) => {
  textCheckMap.value[item.id] = !textCheckMap.value[item.id];
};

const handleFillContent = (text) => {
  emit('out-text', text);
};

const hangleBeforeStr = () => {
  for (const item of elementList.value) {
    if (textCheckMap.value[item.id]) {
      item.text = item.text.slice(1);
    }
  }
};

const handleClear = () => {
  elementList.value = [];
  textCheckMap.value = {};
};

let longPressTimer = null;
const imageViewerIndex = ref(0);
const showPreview = ref(false);
const onTouchstart = (item, index) => {
  clearTimeout(longPressTimer); // 清除计时器
  longPressTimer = null;
  imageViewerIndex.value = index;
  longPressTimer = setTimeout(() => {
    showPreview.value = true;

    console.log('onTouchstart');
  }, 500);
};

const touchEnd = () => {
  console.log('touchEnd');
  clearTimeout(longPressTimer); // 清除计时器
  longPressTimer = null;
};
</script>

<style lang="scss" scoped>
.material-image-read {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  padding: 0 12px;
  box-sizing: border-box;
}

.preview-content {
  border: 1px solid #e6e6e6;
  border-radius: 12px;
  box-sizing: border-box;
  overflow-y: auto;
  width: 100%;
  height: 100%;
}

.text-list {
  overflow: auto;
  // border: 1px solid #e6e6e6;
  // box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  padding: 0 6px;
  box-sizing: border-box;
}

.text-list-item {
  box-sizing: border-box;
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  width: calc(100% / 4);
  padding: 4px;
  box-sizing: border-box;
  aspect-ratio: 1/1;
}

.text-list-warp {
  border: 1px solid #e6e6e6;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  position: relative;
}

.text-list-checkbox {
  margin-right: 0;
  position: absolute;
  right: 6px;
  top: 6px;
  height: auto;
}

.text-list-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
</style>

<style lang="scss">
.editable-handle {
  width: 100%;
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}

.read-editable-content {
  border: 1px solid #e6e6e6;
  border-radius: 8px;
  width: 100%;
  position: relative;
  margin: 0 auto;
  padding: 12px;
  box-sizing: border-box;
  height: 460px;
  outline: none;
  overflow: auto;

  &::after {
    content: attr(placeholder);
    color: #999;
  }
}

.read-editable-content p {
  line-height: 2.8 !important;
  // margin: 0 !important;
  font-size: 12px !important;
  position: relative;

  & * {
    font-size: 12px !important;
  }
}
</style>
